/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package blogic;

import aentity.aeOrdenadorAsc;
import aentity.aeOrdenadorDesc;
import bentity.beDetallePedido;
import bentity.beOrdenDespacho;
import bentity.bePallet;
import bentity.bePedido;
import bentity.beUbicacion;
import dao.daoOrdenDespacho;
import java.sql.Date;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;

/**
 *
 * @author renzo
 */
public class blOrdenDespacho{

    public int registrarOrdenDespacho(beOrdenDespacho orden) throws Exception{
        return (new dao.daoOrdenDespacho()).registrarOrdenDespacho(orden);
    }

    public ArrayList<beOrdenDespacho> obtenerOrdenesPorFiltro(int idOrdenDespacho, String estadoOrdenDespacho, Date fechaDesde, Date fechaHasta) throws Exception{
        return (new dao.daoOrdenDespacho()).queryOrdenesByFilters(idOrdenDespacho, estadoOrdenDespacho, fechaDesde, fechaHasta);
    }

    public beOrdenDespacho obtenerOrdenPorID(int idOrdenDespacho) throws Exception{
        return (new daoOrdenDespacho()).queryOrdenByID(idOrdenDespacho);
    }

    public int modificarOrdenDespacho(beOrdenDespacho ordenDespacho, ArrayList<bePedido> pedidosNuevosElegidos) throws Exception{
        return (new daoOrdenDespacho()).modificarOrdenDespacho(ordenDespacho, pedidosNuevosElegidos);
    }

    public int eliminarOrdenDespacho(int idOrdenDespacho) throws Exception{
        return (new daoOrdenDespacho()).eliminarOrdenDespacho(idOrdenDespacho);
    }

    public ArrayList<beUbicacion> obtenerUbicacionesDisponibles(ArrayList<bePedido> pedidos) throws Exception{
        ArrayList<beUbicacion> ubicsDisp = null;
        ArrayList<beUbicacion> ubicsAct = null;
        ArrayList<beUbicacion> ubicsEleg = new ArrayList<beUbicacion>();
        ArrayList<beDetallePedido> dets = null;
        blUbicacion blu = new blUbicacion();
        blPedido blp = new blPedido();
        int idPedido = -1;
        for(int i=0; i<pedidos.size();i++){
            idPedido = pedidos.get(i).getIdPedido();
            dets = blp.obtenerDetallePedidoPorId(pedidos.get(i).getIdPedido());
            for(int j=0; j<dets.size();j++){
                ubicsDisp = blu.obtenerUbiXProd(dets.get(j).getIdProducto());
                ubicsDisp = this.quitarUbicsYaUtilizadas(ubicsEleg,ubicsDisp);
                ubicsAct = this.elegirUbicaciones(ubicsDisp,dets.get(j).getCantProducto(),1);
                if (ubicsAct == null)
                    ubicsAct = this.elegirUbicaciones(ubicsDisp,dets.get(j).getCantProducto(),2);
                if (ubicsAct == null)
                    return null;
                for(int k=0;k<ubicsAct.size();k++){
                    ubicsAct.get(k).setIdPedido(idPedido);
                }
                ubicsEleg.addAll(ubicsAct);
            }
        }
        return ubicsEleg;
    }

    public ArrayList<beUbicacion> quitarUbicsYaUtilizadas(ArrayList<beUbicacion> ubicsEleg, ArrayList<beUbicacion> ubicsDisp){
        for(int i=0;i<ubicsDisp.size();i++){
            for(int j=0;j<ubicsEleg.size();j++){
                if (ubicsEleg.get(j).getId_ubicacion() == ubicsDisp.get(i).getId_ubicacion()){
                    ubicsDisp.remove(i);
                    break;
                }
            }
        }
        return ubicsDisp;
    }

    private ArrayList<beUbicacion> elegirUbicaciones(ArrayList<beUbicacion> ubicsDisp, int cantProducto, int opc) throws Exception {
        ArrayList<beUbicacion> ubicsEleg = new ArrayList<beUbicacion>();
        ArrayList<bePallet> pallets = this.obtenerTodosLosPallets(ubicsDisp);
        if (opc == 1)
            Collections.sort(pallets,(new aeOrdenadorAsc()));
        if (opc == 2)
            Collections.sort(pallets,(new aeOrdenadorDesc()));
        int cantAct = 0;
        for(int i=0;i<pallets.size();i++){
            if (pallets.get(i).getCantCajas()<=Math.abs(cantProducto-cantAct)){
                cantAct += pallets.get(i).getCantCajas();
                ubicsEleg.add(this.obtenerUbicPorIdPallet(pallets.get(i).getIdUbicacion(),ubicsDisp));
                if (cantProducto == cantAct)
                    break;
            }
        }
        if (cantAct != cantProducto)
            return null;
        return ubicsEleg;
    }

    private beUbicacion obtenerUbicPorIdPallet(int idUbicacion, ArrayList<beUbicacion> ubicsDisp){
        for(int i=0;i<ubicsDisp.size();i++){
            if (ubicsDisp.get(i).getIdUbicacion() == idUbicacion)
                return ubicsDisp.get(i);
        }
        return null;
    }

    public ArrayList<bePallet> obtenerTodosLosPallets(ArrayList<beUbicacion> ubicsDisp) throws Exception{
        ArrayList<bePallet> pallets = new ArrayList<bePallet>();
        bePallet p = null;
        for(int i=0;i<ubicsDisp.size();i++){
            p = (new blPallet()).getPallet(ubicsDisp.get(i).getId_ubicacion());
            p.setIdUbicacion(ubicsDisp.get(i).getId_ubicacion());
            pallets.add(p);
        }
        return pallets;
    }

    public int obtenerNumeroDespachoProducto(int idProducto, int meses) throws Exception{
        return (new daoOrdenDespacho()).obtenerNumeroDespachos(idProducto, meses);
    }

    public ArrayList<beOrdenDespacho> obtenerOrdenesPorDespachar() throws Exception{
        return (new daoOrdenDespacho()).obtenerOrdenesPorDespachar();
    }

    public int colocarOrdenDespachoYPedidosDespachado(int idOrdenDespacho) throws Exception{
        return (new daoOrdenDespacho()).colocarOrdenDespachoYPedidosDespachado(idOrdenDespacho);
    }
    public int quitarUbicacion(int idUbicacion,int idPallet, int orden) throws SQLException{
        return (new daoOrdenDespacho()).quitarUbicacion(idUbicacion, idPallet,orden);
    }
    public int agregarOrden(int idUbicacion,int idOrden) throws SQLException{
        return (new daoOrdenDespacho()).agregarOrden(idUbicacion, idOrden);
    }
}
